package com.lohika  
{
	
	import com.lohika.util.GameUtil;
	
	import events.EntityEvent;
	
	import fl.transitions.Tween;
	import fl.transitions.TweenEvent;
	import fl.transitions.easing.Bounce;
	import fl.transitions.easing.Strong;
	
	import flash.display.*;
	import flash.events.*;
	import flash.geom.Matrix;
	import flash.geom.Rectangle;
	import flash.media.Sound;
	import flash.utils.setTimeout;
	
	/**
	 * Each cell (crystal) of our game
	 * @author Vitaly Vrublevskyy
	 */
	public class Entity extends EventDispatcher 
	{
		public var column:uint;
		public var row:uint;
		public var type:uint;
		
		//UI
		public var container:Sprite;
		private var image:DisplayObject;
		
		//Effects
		private static var tween1:Tween;
		private static var tween2:Tween;
		private var moveTween:Tween;
		
		public function Entity()
		{
			container = new Sprite();
			container.mouseChildren = false;
			container.addEventListener(MouseEvent.CLICK, onClick)
		}

		
		public function setImage(value:DisplayObject):void
		{
			image = container.addChild(value);
		}
		
		public function position(offset:Number):void
		{
			//global
			container.x = column * Constant.ENTITY_SIZE;
			container.y = row * Constant.ENTITY_SIZE;
			
			//local
			image.x = offset/2;
			image.y = offset/2;
		}
		
		public function appear():void
		{
			var endY:Number = image.y;
			moveTween = new Tween(image, "y" , Bounce.easeOut, - 100, endY, 1, true);
		}
		
		public function select():void
		{
			//draw border
			with (container.graphics)
			{
				clear()
				lineStyle(5,0xFFFF00)
				beginFill(0, 0);
				drawRect(0, 0, Constant.ENTITY_SIZE, Constant.ENTITY_SIZE);
				endFill();
			}
		}
		
		public function deselect():void
		{
			container.graphics.clear();
		}
		
		public function isNeighbour(entity:Entity):Boolean
		{
			if ( row == entity.row && Math.abs(column - entity.column) == 1)
			{
				return true;
			}			
			if ( column == entity.column && Math.abs(row - entity.row) == 1)
			{
				return true;
			}
			
			return false;
		}
		
		public function swap(second:Entity):void
		{
			var tempColumn:uint = second.column;
			var tempRow:uint = second.row;
			
			second.column = this.column;
			second.row = this.row;
			this.column = tempColumn;
			this.row = tempRow;
			
			replaceWithEffect(second);
		}
	
		private function replaceWithEffect(second:Entity):void 
		{
			GameUtil.playSound( new SoundReplace() );
			
			var prop:String  = (row == second.row) ? "x" : "y"; //direction
			
			var startCord:Number = container[prop];
			var endCord:Number = second.container[prop];
			tween1 = new Tween(container, prop, Strong.easeOut, startCord, endCord, Constant.EFFECTS_DURATION, true);
			tween2 = new Tween(second.container, prop , Strong.easeOut, endCord, startCord, Constant.EFFECTS_DURATION, true);
			
			container.mouseEnabled = false; //mouse disable for clicking
			setTimeout(finishReplacing, Constant.EFFECTS_DURATION * 1000, second);
		}
		
		private function finishReplacing(second:Entity):void 
		{
			container.mouseEnabled = true;
			
			var first:Entity = this;
			container.dispatchEvent(new EntityEvent(EntityEvent.REPLACED, first, second, true));
		}
		
	
		public function relocate():void
		{
			var startY:Number =  container.y;
			var endY:Number = row * Constant.ENTITY_SIZE; 
			if (moveTween && moveTween.isPlaying)
			{
				moveTween.stop();
			}
			moveTween = new Tween(container, "y" , Strong.easeOut, startY, endY, 1, true);
		}
		
		protected function onClick(event:Event):void
		{
			event.stopPropagation();
			
			container.dispatchEvent(new EntityEvent(EntityEvent.SELECT, this, null, true));
		}
		
	}

}